package com.zzh.partnersys.ai.util;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.UUID;

/**
 * 文件存储工具类
 * 支持本地存储和OSS存储（OSS部分使用占位符，需要替换为实际实现）
 *
 * @author zzh
 * @since 2025-01-XX
 */
@Slf4j
@Component
public class FileStorageUtil {

    /**
     * 文件存储类型：local-本地存储，oss-阿里云OSS
     * TODO: 从配置文件读取，例如：@Value("${file.storage.type:local}")
     */
    @Value("${file.storage.type:local}")
    private String storageType;

    /**
     * 本地存储根路径
     * TODO: 从配置文件读取，例如：@Value("${file.storage.local.path:/data/files}")
     */
    @Value("${file.storage.local.path:./uploads}")
    private String localStoragePath;

    /**
     * OSS访问域名
     * TODO: 从配置文件读取，例如：@Value("${file.storage.oss.domain:}")
     */
    @Value("${file.storage.oss.domain:}")
    private String ossDomain;

    /**
     * 上传文件并返回存储地址
     *
     * @param file 上传的文件
     * @return 文件存储地址（用于RAG读取）
     */
    public String uploadFile(MultipartFile file) throws IOException {
        if (file == null || file.isEmpty()) {
            throw new IllegalArgumentException("文件不能为空");
        }

        // 生成唯一文件名
        String originalFilename = file.getOriginalFilename();
        String fileExtension = "";
        if (originalFilename != null && originalFilename.contains(".")) {
            fileExtension = originalFilename.substring(originalFilename.lastIndexOf("."));
        }
        String fileName = UUID.randomUUID().toString() + fileExtension;

        // 根据存储类型选择不同的存储方式
        if ("oss".equalsIgnoreCase(storageType)) {
            return uploadToOSS(file, fileName);
        } else {
            return uploadToLocal(file, fileName);
        }
    }

    /**
     * 上传文件到本地存储
     *
     * @param file     上传的文件
     * @param fileName 生成的文件名
     * @return 文件存储地址
     */
    private String uploadToLocal(MultipartFile file, String fileName) throws IOException {
        // 按日期创建目录：yyyy/MM/dd
        String datePath = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd"));
        Path uploadPath = Paths.get(localStoragePath, datePath);

        // 创建目录（如果不存在）
        if (!Files.exists(uploadPath)) {
            Files.createDirectories(uploadPath);
        }

        // 保存文件
        Path filePath = uploadPath.resolve(fileName);
        file.transferTo(filePath.toFile());

        // 返回相对路径，例如：/uploads/2025/01/15/uuid.pdf
        String fileUrl = "/" + localStoragePath.replace("\\", "/") + "/" + datePath + "/" + fileName;
        log.info("文件上传成功，本地路径: {}", fileUrl);
        return fileUrl;
    }

    /**
     * 上传文件到OSS（阿里云对象存储）
     * TODO: 替换为实际的OSS上传实现
     * @param file     上传的文件
     * @param fileName 生成的文件名
     * @return 文件存储地址（OSS URL）
     */
    private String uploadToOSS(MultipartFile file, String fileName) throws IOException {
        // TODO: 实现OSS上传逻辑
        // 示例代码（需要引入阿里云OSS SDK）：
        /*
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        String objectName = "ai-assistant/" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd")) + "/" + fileName;
        ossClient.putObject(bucketName, objectName, file.getInputStream());
        String fileUrl = ossDomain + "/" + objectName;
        ossClient.shutdown();
        return fileUrl;
        */
        throw new UnsupportedOperationException("OSS存储功能待实现，请配置OSS相关参数或使用本地存储");
    }


    /**
     * 上传文件minio实现存储
     * TODO: 替换为实际的OSS上传实现
     * @param file     上传的文件
     * @param fileName 生成的文件名
     * @return 文件存储地址（OSS URL）
     */
    private String uploadToMinio(MultipartFile file, String fileName) throws IOException {
        throw new UnsupportedOperationException("minio存储功能待实现，请配置minio相关参数或使用本地存储");
    }


    /**
     * 删除文件
     *
     * @param fileUrl 文件存储地址
     * @return 是否删除成功
     */
    public boolean deleteFile(String fileUrl) {
        if (fileUrl == null || fileUrl.isEmpty()) {
            return false;
        }

        try {
            if ("oss".equalsIgnoreCase(storageType)) {
                return deleteFromOSS(fileUrl);
            } else {
                return deleteFromLocal(fileUrl);
            }
        } catch (Exception e) {
            log.error("删除文件失败，fileUrl: {}", fileUrl, e);
            return false;
        }
    }

    /**
     * 从本地存储删除文件
     *
     * @param fileUrl 文件存储地址
     * @return 是否删除成功
     */
    private boolean deleteFromLocal(String fileUrl) {
        try {
            // 移除开头的斜杠，转换为绝对路径
            String filePath = fileUrl.startsWith("/") ? fileUrl.substring(1) : fileUrl;
            Path path = Paths.get(filePath);
            if (Files.exists(path)) {
                Files.delete(path);
                log.info("本地文件删除成功: {}", fileUrl);
                return true;
            }
            return false;
        } catch (IOException e) {
            log.error("删除本地文件失败，fileUrl: {}", fileUrl, e);
            return false;
        }
    }

    /**
     * 从OSS删除文件
     * TODO: 替换为实际的OSS删除实现
     *
     * @param fileUrl 文件存储地址（OSS URL）
     * @return 是否删除成功
     */
    private boolean deleteFromOSS(String fileUrl) {
        // TODO: 实现OSS删除逻辑
        /*
        try {
            OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
            String objectName = fileUrl.replace(ossDomain + "/", "");
            ossClient.deleteObject(bucketName, objectName);
            ossClient.shutdown();
            return true;
        } catch (Exception e) {
            log.error("删除OSS文件失败，fileUrl: {}", fileUrl, e);
            return false;
        }
        */
        throw new UnsupportedOperationException("OSS存储功能待实现");
    }

    /**
     * 获取文件大小（字节）
     *
     * @param file 文件
     * @return 文件大小
     */
    public long getFileSize(MultipartFile file) {
        return file != null ? file.getSize() : 0;
    }

    /**
     * 获取文件类型
     *
     * @param file 文件
     * @return 文件类型（如pdf、docx、txt）
     */
    public String getFileType(MultipartFile file) {
        if (file == null || file.getOriginalFilename() == null) {
            return "";
        }
        String originalFilename = file.getOriginalFilename();
        if (originalFilename.contains(".")) {
            return originalFilename.substring(originalFilename.lastIndexOf(".") + 1).toLowerCase();
        }
        return "";
    }
}

